#! python
#! -*- coding: utf-8 -*-

__author__ = 'anton'

import subprocess
import re
import itertools


class ImageHash(object):

    PATTERN = r'^\s*PH[1-7]:\s*([\d\.\+\-]+),\s*([\d\.\+\-]+)\s*$'
    LENGTH = 42

    def __init__(self, values=None):
        self.__values = []
        if values is not None:
            self.__values = list(values)
            assert len(self.__values) == ImageHash.LENGTH, 'Get {}'.format(len(self.__values))

    @property
    def values(self):
        return self.__values

    def similar_to(self, other):
        if self and other:
            return sum(map(lambda x, y: (x-y)*(x-y), self.values, other.values))
        return float(1 << 32)

    def __nonzero__(self):
        return bool(self.__values)

    def __str__(self):
        if not self.__values:
            return '<Empty>'
        return str(self.__values)

    def __eq__(self, other):
        return self.similar_to(other)

    @classmethod
    def from_file(cls, filename):
        text = subprocess.check_output(['identify', '-verbose', '-moments', filename.encode('cp1251')])
        pairs = re.findall(cls.PATTERN, text, re.MULTILINE)
        return cls([float(i) for i in itertools.chain.from_iterable(pairs)])

    @classmethod
    def from_stream(cls, data):
        p = subprocess.Popen(['identify', '-verbose', '-moments', '-'],
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             shell=True)
        text = p.communicate(input=data)[0]
        pairs = re.findall(cls.PATTERN, text, re.MULTILINE)
        return cls([float(i) for i in itertools.chain.from_iterable(pairs)])


if __name__ == '__main__':
    data = open(u'D:\\Temp\\Тоха и Анька\\0_ac38b_a4e826_XS.jpg', 'rb').read()
    data_hash = ImageHash.from_stream(data)
    file_hash = ImageHash.from_file(u'D:\\Temp\\Тоха и Анька\\0_ac38b_a4e826_XS.jpg')
    print 'DATA', data_hash, 'LEN', len(data_hash.values)
    print 'FILE', file_hash, 'LEN', len(file_hash.values)
    print 'DIFF', data_hash == file_hash